#include <Hazel.h>
#include "Hazel/Core/EntryPoint.h"
#include "Sandbox2D.h"

//class ExampleLayer : public Hazel::Layer {
//public:
//    ExampleLayer() : Layer("Example") ,m_CameraController(1280.0f/ 720.0f,true){
//        glm::mat4 tests = glm::translate(glm::mat4(1.0f), glm::vec3{0.1,0.2,0.3});
//        glm::mat4 tests2 =  glm::rotate(glm::mat4(1.0f), glm::radians(10.f), glm::vec3(0, 0, 1));
////        HZ_GLM4(tests2);
////        HZ_GLM4(tests * tests2);
////        qipan();
////        qianyidaosanbox();
//        texture();
//        // 拓展vertexSrc，增加u_Transform字段，
//        // 乘到a_Position左边，这就是标准的mvp变换矩阵
////        static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
////        HZ_GLM4(scale);
//    }
//
//    void OnUpdate(Hazel::Timestep ts) override{
//        m_CameraController.OnUpdate(ts);
//
//        Hazel::RenderCommand::SetClearColor({0.45f, 0.55f, 0.60f, 1.00f});
//        Hazel::RenderCommand::Clear();
//
//        Hazel::Renderer::BeginScene(m_CameraController.GetCamera());
//
////        std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_FlatColorShader)->Bind();
////        std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_FlatColorShader)->UploadUniformFloat3("u_Color", m_SquareColor);
////        glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
////
////        for (int y = 0; y < 20; y++) {
////            for (int x = 0; x < 20; x++) {
////                glm::vec3 pos(x * 0.11f, y * 0.11f, 0.0f);
////                glm::mat4 transfrom = glm::translate(glm::mat4(1.0f), pos) * scale;
////
////                Hazel::Renderer::Submit(m_FlatColorShader, m_SquareVA, transfrom);
////            }
////        }
////        Hazel::Renderer::Submit(m_Shader, m_VertexArray);
//        auto textureShader = m_ShaderLibrary.Get("Texture");
//
//        m_Texture->Bind();
//        Hazel::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
//        m_ChernoLogo->Bind();
//        Hazel::Renderer::Submit(textureShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));
//        Hazel::Renderer::EndScene();
//    }
//
////    void OnEvent(Hazel::Event& event) override {
////        if (event.GetEventType() == Hazel::EventType::KeyPressed) {
////            auto& e = dynamic_cast<Hazel::KeyPressedEvent&>(event);
////            if (e.GetKeyCode() == YT_KEY_TAB) {
////                HZ_TRACE("Tab key is pressed(event)!");
////            }
////            HZ_TRACE("{0}", (char)e.GetKeyCode());
////        }
////    }
//    void OnEvent(Hazel::Event& e) override {
//        m_CameraController.OnEvent(e);
//    }
//
//    virtual void OnImGuiRender() override {
//        ImGui::Begin("Settings");
//        ImGui::ColorEdit3("Square Color", glm::value_ptr(m_SquareColor));
//        ImGui::End();
//    }
//
//    void texture(){
//
//        m_VertexArray = Hazel::VertexArray::Create();
//
//        float vertices[3 * 7] = {
//                -0.5f, -0.5f, 0.0f, 0.8f, 0.2f, 0.8f, 1.0f,
//                0.5f, -0.5f, 0.0f, 0.2f, 0.3f, 0.8f, 1.0f,
//                0.0f,  0.5f, 0.0f, 0.8f, 0.8f, 0.2f, 1.0f
//        };
//
//        Hazel::Ref<Hazel::VertexBuffer> vertexBuffer = Hazel::VertexBuffer::Create(vertices, sizeof(vertices));
//        Hazel::BufferLayout layout = {
//                { Hazel::ShaderDataType::Float3, "a_Position" },
//                { Hazel::ShaderDataType::Float4, "a_Color" }
//        };
//        vertexBuffer->SetLayout(layout);
//        m_VertexArray->AddVertexBuffer(vertexBuffer);
//
//        uint32_t indices[3] = { 0, 1, 2 };
//        Hazel::Ref<Hazel::IndexBuffer> indexBuffer = Hazel::IndexBuffer::Create(indices, sizeof(indices) / sizeof(uint32_t));
//        m_VertexArray->SetIndexBuffer(indexBuffer);
//
//        std::string vertexSrc = R"(
//            #version 330 core
//            layout(location = 0) in vec3 a_Position;
//            layout(location = 1) in vec4 a_Color;
//
//            uniform mat4 u_ViewProjection;
//            uniform mat4 u_Transform;
//
//            out vec3 v_Position;
//            out vec4 v_Color;
//            void main()
//            {
//                v_Position = a_Position;
//                v_Color = a_Color;
//                gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
//            }
//        )";
//
//        std::string fragmentSrc = R"(
//            #version 330 core
//            layout(location = 0) out vec4 color;
//            in vec3 v_Position;
//            in vec4 v_Color;
//
//            void main()
//            {
//                color = vec4(v_Position * 0.5 + 0.5, 1.0);
//                color = v_Color;
//            }
//        )";
//
////        m_Shader.reset(Hazel::Shader::Create(vertexSrc, fragmentSrc));
//        m_Shader = Hazel::Shader::Create("VertexPosColor", vertexSrc, fragmentSrc);
//
////        m_SquareVA.reset(Hazel::VertexArray::Create());
//
//        float squareVertices[5*4] = {
//                -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
//                0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
//                0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
//                -0.5f, 0.5f, 0.0f, 0.0f, 1.0f
//        };
//
//        Hazel::Ref<Hazel::VertexBuffer> squareVB = Hazel::VertexBuffer::Create(squareVertices, sizeof(squareVertices));
//        squareVB->SetLayout({
//                                    { Hazel::ShaderDataType::Float3, "a_Position" },
//                                    { Hazel::ShaderDataType::Float2, "a_TexCoord" }
//                            });
//        m_SquareVA->AddVertexBuffer(squareVB);
//        uint32_t squareIndices[6] = {0,1,2,2,3,0};
//        Hazel::Ref<Hazel::IndexBuffer> squareIB = Hazel::IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t));
//        m_SquareVA->SetIndexBuffer(squareIB);
//
////        m_TextureShader.reset(Hazel::Shader::Create("../assets/shaders/Texture.glsl"));
//        auto textureShader = m_ShaderLibrary.Load("../assets/shaders/Texture.glsl");
//        m_Texture = Hazel::Texture2D::Create("../assets/textures/Checkerboard.png");
//        m_ChernoLogo = Hazel::Texture2D::Create("../assets/textures/ChernoLogo.png");
////        std::dynamic_pointer_cast<Hazel::OpenGLShader>(m_TextureShader)->Bind();
//        textureShader->Bind();
//        textureShader->SetInt("u_Texture", 0);
//
//    }
//private:
//    Hazel::OrthographicCameraController m_CameraController;
//    Hazel::ShaderLibrary m_ShaderLibrary;
//    Hazel::Ref<Hazel::Shader> m_Shader;
//    Hazel::Ref<Hazel::VertexArray> m_VertexArray;
//    Hazel::Ref<Hazel::Texture2D> m_Texture,m_ChernoLogo;
//    Hazel::Ref<Hazel::VertexArray> m_SquareVA;
//    glm::vec3 m_CameraPosition{0.5f, 0.0f, 0.0f};
//    glm::vec3 m_SquareColor = {0.2f, 0.3f, 0.8f};
//};
/* *
 * sandbox 继承APP 所以等同new application
 * create window对象，并且挂载到app实例的 m_window 属性上
 * m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent)); 把函数绑定到 windowwindow.WindowData.EventCallback.Onevent里会遍历m_LayerStack执行里面的onevent
 * create函数里执行WindowsWindow::Init->  glfwMakeContextCurrent 里边构造了glfw的窗口 并且绑定了GLFW的回调函数 最终执行了 windowwindow.WindowData.EventCallback 这个函数。并且使用了闭包，在闭包里声明了参数
 * layer 分层，在初始化的时候PushOverlay执行这个方法。 会把layer实例push到m_LayerStack这个属性里，并且执行OnAttach初始化
 * 在主循环里。会不停的遍历m_LayerStack->onupdate方法
 *
 * 按键相应，首选声明全局静态application变量，在使用getwindow获取窗口对象。通过window获取glfwweindow->glfwGetKey 获取什么键被按下
 * 第一部分称为Renderer，第二部分称为RenderCommand，为了跨平台，对图形API还封装了一层RendererAPI，调用关系如下图：
 * Renderer派发任务到RenderCommand(再初始化的时候就指定了randerApi属性) 派发到randerApi->DrawIndexed
 * */
class Sandbox : public Hazel::Application{
public:
    Sandbox(){
//        PushOverlay(new ExampleLayer());
//        PushOverlay(new Hazel::ImGuiLayer());
        PushOverlay(new Sandbox2D());
    };
    ~Sandbox(){

    }
};

Hazel::Application* Hazel::CreateApplication(){
    return new Sandbox();
}
